package com.sinodata.bsm.cicp.collector.sqlserver;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.AbstractJDBCCollector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.DBConnectionUtil;
import com.sinodata.bsm.common.constants.SeparatorConstants;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class LogFile extends AbstractJDBCCollector {
    private static final Logger logger = Logger.getLogger(LogFile.class);

    //    private static final int DEADLOCK_WAIT_TIME = 60;

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {

        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        try {
            String[] propMetas = getPropMeta();
            //        String serverName = this.getParamMap().get("服务器名");
            String serverName = this.getParamMap().get("ServerName");

            String sql = "sp_helpdb";
            String[] rs = this.getStrings(serverName, sql, ip);

            ResPropertyValue propertyValueX = new ResPropertyValue();
            ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
            for (int i = 0; i < propMetas.length; i++) {
                propValues[i] = ResPropertyValue.createPropValue(rs[i], propMetas[i]);
            }

            propertyValueX.setValues(propValues);
            values.add(propertyValueX);
        } catch (Exception e) {
            logger.error("failed to collect sqlserver log files", e);
            throw new CollectorException(e);
        }
        return values;
    }

    private String[] getStrings(String serverName, String sql, String ip) throws CollectorException {
        String[] propValArr = new String[6];
        CallableStatement cstmt = null;
        ResultSet rst = null;
        Connection conn = null;
        try {
            conn = DBConnectionUtil.getInstance().getConnection("sqlserver", ip, serverName);
            if (conn == null) {
                return null;
            }
            cstmt = conn.prepareCall(sql);
            cstmt.setQueryTimeout(10);
            rst = cstmt.executeQuery();
            List dbnameList = new ArrayList();
            if (rst != null) {
                while (rst.next()) {
                    dbnameList.add(rst.getString(1));
                }
            }

            int fileCount = 0;
            StringBuffer fileDetail = new StringBuffer();
            // 名称,文件ID,物理文件名,数据库名,大小,最大大小,增量
            //            fileDetail.append("Name").append(SeparatorConstants.COL_SEPARATOR);//名称
            //            fileDetail.append("File ID").append(SeparatorConstants.COL_SEPARATOR);//文件ID
            //            fileDetail.append("Physics File Name").append(SeparatorConstants.COL_SEPARATOR);//物理文件名
            //            fileDetail.append("Database Name").append(SeparatorConstants.COL_SEPARATOR);//数据库名
            //            fileDetail.append("Size").append(SeparatorConstants.COL_SEPARATOR);//大小
            //            fileDetail.append("Max").append(SeparatorConstants.COL_SEPARATOR);//最大大小
            //            fileDetail.append("Increment").append(SeparatorConstants.COL_SEPARATOR);//增量
            //            fileDetail.append(SeparatorConstants.LIN_SEPARATOR);

            // Iterate database
            Iterator it = dbnameList.iterator();
            String dbname = "";
            while (it.hasNext()) {
                dbname = it.next().toString();

                sql = "{call " + dbname + ".dbo.sp_helpfile}";
                cstmt = conn.prepareCall(sql);
                rst = cstmt.executeQuery();
                if (rst != null) {
                    while (rst.next()) {
                        String usage = rst.getString(8);
                        if (usage != null)
                            usage = usage.trim();
                        if (usage.equals("log only")) {
                            fileCount++;
                            String line = getTabLineStr(rst, dbname);
                            fileDetail.append(line).append(SeparatorConstants.LIN_SEPARATOR);
                        }
                    }
                }

            }
            String fileDetailstr = fileDetail.toString();

            propValArr[0] = "" + fileCount;
            propValArr[1] = fileDetailstr;

        } catch (Exception ex) {
            logger.error("while connect database ", ex);

            throw new CollectorException(ex);
        } finally {

            if (rst != null) {
                try {
                    rst.close();
                } catch (SQLException e) {
                    logger.error("failed to close result set", e);
                    throw new CollectorException(e);
                }
            }
            if (cstmt != null) {
                try {
                    cstmt.close();
                } catch (SQLException e) {
                    logger.error("failed to close statement", e);
                    throw new CollectorException(e);
                }
            }
            DBConnectionUtil.getInstance().returnConnection(conn);
        }

        return propValArr;
    }

    private String getTabLineStr(ResultSet rst, String dbname) throws CollectorException {
        StringBuffer tabLineStr = new StringBuffer();
        int colNum = 7;
        try {
            for (int i = 1; i <= colNum; i++) {
                String val = rst.getString(i);
                if (val == null || val.trim().length() == 0) {
                    val = " ";
                } else
                    val = val.trim();
                if (i == 4) // 将文件组列替换为数据库名
                    val = dbname;
                // if (i != colNum)
                tabLineStr.append(val).append(SeparatorConstants.COL_SEPARATOR);
                // else
                // tabLineStr.append(val);
            }
        } catch (Exception e) {
            logger.error("failed to get TabLineStr ", e);

            throw new CollectorException(e);
        }
        return tabLineStr.toString();
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "ServerName" };
    }

    @Override
    public String[] getPropMeta() {
        //        return new String[] { "日志文件个数", "日志文件详细信息" };
        return new String[] { "LogFiles", "LogFilesDetailedInfo" };
    }

}
